package com.xp.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xp.dto.flow.FlowDefinitionDTO;
import com.xp.dto.flow.FlowDefinitionRequest;
import com.xp.dto.flow.FlowQueryRequest;
import com.xp.dto.flow.StatusUpdateRequest;
import com.xp.entity.FlowDefinition;
import com.xp.mapper.FlowDefinitionMapper;
import com.xp.service.FlowDefinitionService;
import com.xp.service.FlowDataConvertService;
import com.xp.dto.LiteFlowConvertResult;
import com.xp.utils.Result;
import java.util.Map;
import java.util.HashMap;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 流程定义服务实现类
 * 
 * @author xp
 * @since 2025-01-01
 */
@Service
@RequiredArgsConstructor
public class FlowDefinitionServiceImpl extends BaseServiceImpl<FlowDefinitionMapper, FlowDefinition> implements FlowDefinitionService {

    private static final Logger log = LoggerFactory.getLogger(FlowDefinitionServiceImpl.class);

    private final FlowDefinitionMapper flowDefinitionMapper;
    private final FlowDataConvertService flowDataConvertService;

    /**
     * 分页查询流程定义列表
     */
    @Override
    public Result<IPage<FlowDefinitionDTO>> getFlowDefinitionPage(Page<FlowDefinition> page, FlowQueryRequest queryRequest) {
        try {
            IPage<FlowDefinition> flowPage = flowDefinitionMapper.selectFlowDefinitionPage(
                page,
                queryRequest.getFlowCode(),
                queryRequest.getFlowName(),
                queryRequest.getCategory(),
                queryRequest.getStatusList(),
                queryRequest.getVersion(),
                queryRequest.getApplicationName(),
                queryRequest.getCreatorId(),
                queryRequest.getCreateTimeStart(),
                queryRequest.getCreateTimeEnd(),
                queryRequest.getOrderBy(),
                queryRequest.getOrderDirection()
            );

            // 转换为DTO
            IPage<FlowDefinitionDTO> dtoPage = flowPage.convert(this::convertToDTO);
            return Result.success(dtoPage);
        } catch (Exception e) {
            log.error("分页查询流程定义列表失败", e);
            return Result.error("查询流程定义列表失败");
        }
    }

    /**
     * 创建流程定义
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Long> createFlowDefinition(FlowDefinitionRequest request) {
        try {
            // 验证流程编码唯一性
            if (StringUtils.hasText(request.getFlowCode())) {
                FlowDefinition existingFlow = flowDefinitionMapper.selectByFlowCode(request.getFlowCode());
                if (existingFlow != null) {
                    return Result.error("流程编码已存在");
                }
            }

            // 验证流程名称唯一性
            if (StringUtils.hasText(request.getFlowName())) {
                FlowDefinition existingFlow = flowDefinitionMapper.selectByFlowName(request.getFlowName());
                if (existingFlow != null) {
                    return Result.error("流程名称已存在");
                }
            }

            // 创建流程定义实体
            FlowDefinition flowDefinition = new FlowDefinition();
            BeanUtils.copyProperties(request, flowDefinition);
            
            // 设置默认值
            if (flowDefinition.getStatus() == null) {
                flowDefinition.setStatus(0); // 默认草稿状态
            }
            if (!StringUtils.hasText(flowDefinition.getVersion())) {
                flowDefinition.setVersion("1.0.0"); // 默认版本
            }

            int result = flowDefinitionMapper.insert(flowDefinition);
            if (result > 0) {
                log.info("创建流程定义成功，流程ID：{}，流程编码：{}", flowDefinition.getId(), flowDefinition.getFlowCode());
                return Result.success(flowDefinition.getId());
            } else {
                return Result.error("创建流程定义失败");
            }
        } catch (Exception e) {
            log.error("创建流程定义失败", e);
            return Result.error("创建流程定义失败");
        }
    }

    /**
     * 更新流程定义
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Object> updateFlowDefinition(Long id, FlowDefinitionRequest request) {
        try {
            if (id == null) {
                return Result.error("流程定义ID不能为空");
            }

            // 检查流程定义是否存在
            FlowDefinition existingFlow = flowDefinitionMapper.selectById(id);
            if (existingFlow == null) {
                return Result.error("流程定义不存在");
            }

            // 验证流程编码唯一性（排除自己）
            if (StringUtils.hasText(request.getFlowCode())) {
                FlowDefinition flowByCode = flowDefinitionMapper.selectByFlowCode(request.getFlowCode());
                if (flowByCode != null && !flowByCode.getId().equals(id)) {
                    return Result.error("流程编码已存在");
                }
            }

            // 验证流程名称唯一性（排除自己）
            if (StringUtils.hasText(request.getFlowName())) {
                FlowDefinition flowByName = flowDefinitionMapper.selectByFlowName(request.getFlowName());
                if (flowByName != null && !flowByName.getId().equals(id)) {
                    return Result.error("流程名称已存在");
                }
            }

            // 更新流程定义
            FlowDefinition flowDefinition = new FlowDefinition();
            BeanUtils.copyProperties(request, flowDefinition);
            flowDefinition.setId(id);

            int result = flowDefinitionMapper.updateById(flowDefinition);
            if (result > 0) {
                log.info("更新流程定义成功，流程ID：{}", id);
                return Result.success("更新流程定义成功");
            } else {
                return Result.error("更新流程定义失败");
            }
        } catch (Exception e) {
            log.error("更新流程定义失败", e);
            return Result.error("更新流程定义失败");
        }
    }

    /**
     * 删除流程定义
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Object> deleteFlowDefinition(Long id) {
        try {
            if (id == null) {
                return Result.error("流程定义ID不能为空");
            }

            // 检查流程定义是否存在
            FlowDefinition flowDefinition = flowDefinitionMapper.selectById(id);
            if (flowDefinition == null) {
                return Result.error("流程定义不存在");
            }

            // TODO: 检查是否有正在执行的流程实例

            // 逻辑删除流程定义
            int result = flowDefinitionMapper.deleteById(id);
            if (result > 0) {
                log.info("删除流程定义成功，流程ID：{}", id);
                return Result.success("删除流程定义成功");
            } else {
                return Result.error("删除流程定义失败");
            }
        } catch (Exception e) {
            log.error("删除流程定义失败", e);
            return Result.error("删除流程定义失败");
        }
    }

    /**
     * 根据ID获取流程定义详情
     */
    @Override
    public Result<FlowDefinitionDTO> getFlowDefinitionById(Long id) {
        try {
            if (id == null) {
                return Result.error("流程定义ID不能为空");
            }

            FlowDefinition flowDefinition = flowDefinitionMapper.selectById(id);
            if (flowDefinition == null) {
                return Result.error("流程定义不存在");
            }

            FlowDefinitionDTO dto = convertToDTO(flowDefinition);
            return Result.success(dto);
        } catch (Exception e) {
            log.error("获取流程定义详情失败", e);
            return Result.error("获取流程定义详情失败");
        }
    }

    /**
     * 根据流程编码获取流程定义
     */
    @Override
    public Result<FlowDefinitionDTO> getFlowDefinitionByCode(String flowCode) {
        try {
            if (!StringUtils.hasText(flowCode)) {
                return Result.error("流程编码不能为空");
            }

            FlowDefinition flowDefinition = flowDefinitionMapper.selectByFlowCode(flowCode);
            if (flowDefinition == null) {
                return Result.error("流程定义不存在");
            }

            FlowDefinitionDTO dto = convertToDTO(flowDefinition);
            return Result.success(dto);
        } catch (Exception e) {
            log.error("根据流程编码获取流程定义失败", e);
            return Result.error("获取流程定义失败");
        }
    }

    /**
     * 根据流程编码和版本获取流程定义
     */
    @Override
    public Result<FlowDefinitionDTO> getFlowDefinitionByCodeAndVersion(String flowCode, String version) {
        try {
            if (!StringUtils.hasText(flowCode) || !StringUtils.hasText(version)) {
                return Result.error("流程编码和版本不能为空");
            }

            FlowDefinition flowDefinition = flowDefinitionMapper.selectByFlowCodeAndVersion(flowCode, version);
            if (flowDefinition == null) {
                return Result.error("流程定义不存在");
            }

            FlowDefinitionDTO dto = convertToDTO(flowDefinition);
            return Result.success(dto);
        } catch (Exception e) {
            log.error("根据流程编码和版本获取流程定义失败", e);
            return Result.error("获取流程定义失败");
        }
    }

    /**
     * 获取所有启用的流程定义
     */
    @Override
    public Result<List<FlowDefinitionDTO>> getEnabledFlowDefinitions() {
        try {
            List<FlowDefinition> flowDefinitions = flowDefinitionMapper.selectEnabledFlowDefinitions();
            List<FlowDefinitionDTO> dtoList = flowDefinitions.stream()
                    .map(this::convertToDTO)
                    .collect(Collectors.toList());
            return Result.success(dtoList);
        } catch (Exception e) {
            log.error("获取启用的流程定义失败", e);
            return Result.error("获取流程定义列表失败");
        }
    }

    /**
     * 根据应用名称获取流程定义列表
     */
    @Override
    public Result<List<FlowDefinitionDTO>> getFlowDefinitionsByApplication(String applicationName) {
        try {
            if (!StringUtils.hasText(applicationName)) {
                return Result.error("应用名称不能为空");
            }

            List<FlowDefinition> flowDefinitions = flowDefinitionMapper.selectByApplicationName(applicationName);
            List<FlowDefinitionDTO> dtoList = flowDefinitions.stream()
                    .map(this::convertToDTO)
                    .collect(Collectors.toList());
            return Result.success(dtoList);
        } catch (Exception e) {
            log.error("根据应用名称获取流程定义失败", e);
            return Result.error("获取流程定义列表失败");
        }
    }

    /**
     * 根据分类获取流程定义列表
     */
    @Override
    public Result<List<FlowDefinitionDTO>> getFlowDefinitionsByCategory(String category) {
        try {
            if (!StringUtils.hasText(category)) {
                return Result.error("流程分类不能为空");
            }

            List<FlowDefinition> flowDefinitions = flowDefinitionMapper.selectByCategory(category);
            List<FlowDefinitionDTO> dtoList = flowDefinitions.stream()
                    .map(this::convertToDTO)
                    .collect(Collectors.toList());
            return Result.success(dtoList);
        } catch (Exception e) {
            log.error("根据分类获取流程定义失败", e);
            return Result.error("获取流程定义列表失败");
        }
    }

    /**
     * 更新流程定义状态
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Object> updateFlowDefinitionStatus(Long id, StatusUpdateRequest statusRequest) {
        try {
            if (id == null) {
                return Result.error("流程定义ID不能为空");
            }

            // 检查流程定义是否存在
            FlowDefinition flowDefinition = flowDefinitionMapper.selectById(id);
            if (flowDefinition == null) {
                return Result.error("流程定义不存在");
            }

            int result = flowDefinitionMapper.updateStatus(id, statusRequest.getStatus(), statusRequest.getRemark());
            if (result > 0) {
                log.info("更新流程定义状态成功，流程ID：{}，状态：{}", id, statusRequest.getStatus());
                return Result.success("更新状态成功");
            } else {
                return Result.error("更新状态失败");
            }
        } catch (Exception e) {
            log.error("更新流程定义状态失败", e);
            return Result.error("更新状态失败");
        }
    }

    /**
     * 发布流程定义
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Object> publishFlowDefinition(Long id) {
        try {
            StatusUpdateRequest statusRequest = new StatusUpdateRequest();
            statusRequest.setStatus(1); // 发布状态
            statusRequest.setRemark("流程定义发布");
            return updateFlowDefinitionStatus(id, statusRequest);
        } catch (Exception e) {
            log.error("发布流程定义失败", e);
            return Result.error("发布流程定义失败");
        }
    }

    /**
     * 下线流程定义
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Object> unpublishFlowDefinition(Long id) {
        try {
            StatusUpdateRequest statusRequest = new StatusUpdateRequest();
            statusRequest.setStatus(2); // 下线状态
            statusRequest.setRemark("流程定义下线");
            return updateFlowDefinitionStatus(id, statusRequest);
        } catch (Exception e) {
            log.error("下线流程定义失败", e);
            return Result.error("下线流程定义失败");
        }
    }

    // TODO: 实现其他业务方法
    @Override
    public Result<Long> copyFlowDefinition(Long id, String newFlowCode, String newFlowName) {
        // TODO: 实现流程定义复制逻辑
        return Result.error("功能暂未实现");
    }

    @Override
    public Result<Object> validateFlowConfig(String flowDefinition, String nodeDefinitions) {
        // TODO: 实现LiteFlow配置验证逻辑
        return Result.error("功能暂未实现");
    }

    @Override
    public Result<List<String>> getFlowVersions(String flowCode) {
        // TODO: 实现获取流程版本列表逻辑
        return Result.error("功能暂未实现");
    }

    @Override
    public Result<Long> createFlowVersion(Long id, String version) {
        // TODO: 实现创建流程版本逻辑
        return Result.error("功能暂未实现");
    }

    @Override
    public Result<Object> getFlowDefinitionStatistics() {
        // TODO: 实现流程定义统计逻辑
        return Result.error("功能暂未实现");
    }

    @Override
    public Result<Object> exportFlowDefinition(Long id) {
        // TODO: 实现流程定义导出逻辑
        return Result.error("功能暂未实现");
    }

    @Override
    public Result<Long> importFlowDefinition(String flowData) {
        // TODO: 实现流程定义导入逻辑
        return Result.error("功能暂未实现");
    }

    /**
     * 保存流程设计数据
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Object> saveFlowDesign(Long id, Object flowData) {
        try {
            // 验证流程定义是否存在
            FlowDefinition flowDefinition = flowDefinitionMapper.selectById(id);
            if (flowDefinition == null) {
                return Result.error("流程定义不存在");
            }

            // 将流程图数据转换为JSON字符串保存
            String flowDataJson = null;
            if (flowData != null) {
                // 使用Jackson将对象转换为JSON字符串
                com.fasterxml.jackson.databind.ObjectMapper objectMapper = new com.fasterxml.jackson.databind.ObjectMapper();
                flowDataJson = objectMapper.writeValueAsString(flowData);
            }

            // 更新流程定义的设计数据
            flowDefinition.setFlowData(flowDataJson);
            flowDefinition.setUpdateTime(java.time.LocalDateTime.now());
            
            int result = flowDefinitionMapper.updateById(flowDefinition);
            if (result > 0) {
                log.info("保存流程设计数据成功，流程ID: {}", id);
                return Result.success("保存成功");
            } else {
                return Result.error("保存失败");
            }
        } catch (Exception e) {
            log.error("保存流程设计数据失败，流程ID: {}", id, e);
            return Result.error("保存失败: " + e.getMessage());
        }
    }

    /**
     * 转换LogicFlow数据为LiteFlow规则
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Object> convertToLiteFlow(Long id) {
        try {
            if (id == null) {
                return Result.error("流程定义ID不能为空");
            }

            // 获取流程定义
            FlowDefinition flowDefinition = flowDefinitionMapper.selectById(id);
            if (flowDefinition == null) {
                return Result.error("流程定义不存在");
            }

            // 检查是否有流程图数据
            if (!StringUtils.hasText(flowDefinition.getFlowData())) {
                return Result.error("流程图数据为空，请先设计流程图");
            }

            // 转换LogicFlow数据为LiteFlow规则
            LiteFlowConvertResult convertResult = flowDataConvertService.convertToLiteFlow(flowDefinition.getFlowData());
            
            if (!convertResult.isSuccess()) {
                return Result.error("转换失败: " + convertResult.getErrorMessage());
            }

            // 更新流程定义的LiteFlow配置
            flowDefinition.setLiteflowConfig(convertResult.getElExpression());
            flowDefinition.setUpdateTime(java.time.LocalDateTime.now());
            
            int result = flowDefinitionMapper.updateById(flowDefinition);
            if (result > 0) {
                log.info("流程定义转换成功，流程ID: {}, EL表达式: {}", id, convertResult.getElExpression());
                
                // 返回转换结果
                Map<String, Object> responseData = new HashMap<>();
                responseData.put("elExpression", convertResult.getElExpression());
                responseData.put("nodeComponentMapping", convertResult.getNodeComponentMapping());
                responseData.put("statistics", convertResult.getStatistics());
                responseData.put("warnings", convertResult.getWarnings());
                
                return Result.success(responseData);
            } else {
                return Result.error("保存转换结果失败");
            }
        } catch (Exception e) {
            log.error("转换LogicFlow数据为LiteFlow规则失败，流程ID: {}", id, e);
            return Result.error("转换失败: " + e.getMessage());
        }
    }

    /**
     * 预览LiteFlow EL表达式
     */
    @Override
    public Result<Object> previewLiteFlowExpression(Object flowData) {
        try {
            if (flowData == null) {
                return Result.error("流程图数据不能为空");
            }

            com.fasterxml.jackson.databind.ObjectMapper objectMapper = new com.fasterxml.jackson.databind.ObjectMapper();
            
            // 直接将前端数据转换为JSON字符串
            String flowDataJson;
            if (flowData instanceof String) {
                flowDataJson = (String) flowData;
            } else {
                flowDataJson = objectMapper.writeValueAsString(flowData);
            }

            log.info("接收到的流程数据: {}", flowDataJson);

            // 转换LogicFlow数据为LiteFlow规则
            LiteFlowConvertResult convertResult = flowDataConvertService.convertToLiteFlow(flowDataJson);
            
            if (!convertResult.isSuccess()) {
                return Result.error("预览失败: " + convertResult.getErrorMessage());
            }

            // 返回预览结果
            Map<String, Object> responseData = new HashMap<>();
            responseData.put("elExpression", convertResult.getElExpression());
            responseData.put("nodeComponentMapping", convertResult.getNodeComponentMapping());
            responseData.put("statistics", convertResult.getStatistics());
            responseData.put("warnings", convertResult.getWarnings());
            responseData.put("isPreview", true);
            
            log.info("预览LiteFlow EL表达式成功: {}", convertResult.getElExpression());
            return Result.success(responseData);
            
        } catch (Exception e) {
            log.error("预览LiteFlow EL表达式失败", e);
            return Result.error("预览失败: " + e.getMessage());
        }
    }

    /**
     * 转换实体为DTO
     */
    private FlowDefinitionDTO convertToDTO(FlowDefinition flowDefinition) {
        FlowDefinitionDTO dto = new FlowDefinitionDTO();
        BeanUtils.copyProperties(flowDefinition, dto);
        return dto;
    }
}